// SmilParser.cpp: implementation of the CSmilParser class.
//
//////////////////////////////////////////////////////////////////////

#include "SmilParser.h"
#include "XMLDoc.h"
#include <algorithm>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define CONTENT_POS_PROGRAM					"smil/body/video"
#define PROPERTY_NAME_SOURCE				"src"
#define PROPERTY_NAME_STARTTIME				"xStartTime"

CSmilParser::CSmilParser()
{
	m_pDoc = NULL;
}

CSmilParser::~CSmilParser()
{
	delete m_pDoc;
}

Bool CSmilParser::Execute( const string& strFileName )
{
	string strTemp = strFileName;
	std::replace( strTemp.begin(), strTemp.end(), kBadPathDelimiterChar, kPathDelimiterChar );
	if ( NULL == m_pDoc )
	{
		if ( strTemp.empty() )
		{
			return FALSE;
		}
		m_pDoc = new XMLDoc(strTemp.c_str());
		if ( NULL == m_pDoc )
		{
			return FALSE;
		}
	}
	if ( !m_pDoc->LoadXMLDoc() )
	{
		delete m_pDoc;
		m_pDoc = NULL;
		return FALSE;
	}	
	return TRUE;
}

Bool CSmilParser::GetSource( string& outVal )
{
	return GetProperty( CONTENT_POS_PROGRAM, PROPERTY_NAME_SOURCE, outVal );
}

Bool CSmilParser::GetStartTime( string& outVal )
{
	return GetProperty( CONTENT_POS_PROGRAM, PROPERTY_NAME_STARTTIME, outVal );
}

XMLNode* CSmilParser::GetNode( const string& strPos )
{
	if ( NULL == m_pDoc ) return FALSE;
	
	vector<string> vecKey;
	
	SplitString( strPos, vecKey );
	
	XMLNode* pNode = m_pDoc->GetRootNode(vecKey[0].c_str());
	if ( pNode == NULL ) return FALSE;
	
	XMLNode* pNode2 = NULL;
	for ( Int32 i = 1; i < vecKey.size(); i++ )
	{
		pNode2 = pNode->GetChild( vecKey[i] );
		if ( pNode2 == NULL ) return FALSE;
		pNode = pNode2;
	}
	return pNode;
}

Bool CSmilParser::GetContent( const string& strPos, string& outVal )
{
	XMLNode* pNode = GetNode( strPos );
	if ( NULL == pNode ) return FALSE;
	outVal = pNode->GetContent();

	return TRUE;
}

Bool CSmilParser::GetProperty( const string& strPos, const string& strProperty, string& outVal )
{
	XMLNode* pNode = GetNode( strPos );
	if ( NULL == pNode ) return FALSE;
	outVal = pNode->GetProperty( strProperty );
	
	return TRUE;
}

Bool CSmilParser::SetContent( const string& strPos, const string& inVal )
{
	XMLNode* pNode = GetNode( strPos );
	if ( NULL == pNode ) return FALSE;
	return pNode->SetContent( inVal );
}

Bool CSmilParser::SetProperty( const string& strPos, const string& strProperty, const string& inVal )
{
	XMLNode* pNode = GetNode( strPos );
	if ( NULL == pNode ) return FALSE;
	return pNode->ModifyProperty( strProperty, inVal );
}

void CSmilParser::SplitString( const string& inStr, vector<string>& outVec, const string Delimiter )
{
	Int32 Begin = 0;
	Int32 End = 0;
	string key;
	Int32 DelimiterLen = Delimiter.length();
	Begin = inStr.find( Delimiter );
	Begin = ( Begin == 0 ) ? DelimiterLen : 0;
	do
	{
		End = inStr.find( Delimiter, Begin );
		End = ( End == -1 ) ? inStr.length() : End;
		
		key = inStr.substr(Begin, End-Begin);
		if ( !key.empty() ) 
		{
			outVec.push_back(key);
		}
		Begin = End + DelimiterLen;
	}
	while ( End < inStr.length() );
}

Bool CSmilParser::CloneSmil( const string& strFileName )
{
	const char* pSmilString = "<smil><head></head><body><video src=\"program-name\" xStartTime=\"start-datetime\"/></body></smil>";
	string strTemp = strFileName;
	std::replace( strTemp.begin(), strTemp.end(), kBadPathDelimiterChar, kPathDelimiterChar );
	if ( NULL == m_pDoc )
	{
		if ( strTemp.empty() )
		{
			return FALSE;
		}
		m_pDoc = new XMLDoc(strTemp.c_str());
		if ( NULL == m_pDoc )
		{
			return FALSE;
		}
	}
	if ( !m_pDoc->LoadXML( pSmilString ) )
	{
		delete m_pDoc;
		m_pDoc = NULL;
		return FALSE;
	}	
	return TRUE;
}

Bool CSmilParser::SetSource( const string& inVal )
{
	return SetProperty( CONTENT_POS_PROGRAM, PROPERTY_NAME_SOURCE, inVal );
}

Bool CSmilParser::SetStartTime( const string& inVal )
{
	return SetProperty( CONTENT_POS_PROGRAM, PROPERTY_NAME_STARTTIME, inVal );
}

Bool CSmilParser::SaveFile()
{
	if ( NULL == m_pDoc ) return FALSE;
	return m_pDoc->SaveFile();
}